#include <iostream>
#include <string>

// C++17前，头文件中的全局常量通常这样定义:
// header.h
const int MAX_SIZE = 100;  // 每个包含该头文件的cpp都有一个副本
// 或者使用extern:
// extern const int BUFFER_SIZE;
// 然后在一个cpp文件中定义:
// const int BUFFER_SIZE = 1024;

// C++17: 使用inline变量
inline int counter = 0;  // 在头文件中定义，多个编译单元共享同一个实例

// 常量也可以是inline的
inline constexpr double PI = 3.14159265358979;

// 在命名空间中使用inline变量
namespace config {
    inline std::string app_name = "C++17特性演示";
    inline int version = 1;
}

// 在类中使用inline静态成员
class MyClass {
public:
    // C++17前需要在类外定义静态成员
    // static const int VALUE;
    // 现在可以直接在类内内联定义
    inline static const int VALUE = 42;
    inline static std::string name = "MyClass";
};

// 以前的方式需要在cpp文件中定义
// const int MyClass::VALUE = 42;

// 带模板的内联变量
template<typename T>
inline T default_value = T{};  // 默认值

// 特化
template<>
inline std::string default_value<std::string> = "默认字符串";

template<>
inline int default_value<int> = 100;

void demonstrate_inline_variables() {
    std::cout << "  基本内联变量演示:\n";
    std::cout << "  counter初始值: " << counter << '\n';
    counter++;
    std::cout << "  counter增加后: " << counter << '\n';
    
    std::cout << "  内联常量PI: " << PI << '\n';
    
    std::cout << "\n  命名空间内联变量:\n";
    std::cout << "  应用名称: " << config::app_name << '\n';
    std::cout << "  版本号: " << config::version << '\n';
    
    // 修改内联变量
    config::app_name = "更新的应用名称";
    std::cout << "  更新后的应用名称: " << config::app_name << '\n';
    
    std::cout << "\n  类内联静态成员:\n";
    std::cout << "  MyClass::VALUE = " << MyClass::VALUE << '\n';
    std::cout << "  MyClass::name = " << MyClass::name << '\n';
    
    MyClass::name = "更新的类名";
    std::cout << "  更新后的类名: " << MyClass::name << '\n';
    
    std::cout << "\n  模板内联变量:\n";
    std::cout << "  default_value<int> = " << default_value<int> << '\n';
    std::cout << "  default_value<double> = " << default_value<double> << '\n';
    std::cout << "  default_value<std::string> = " << default_value<std::string> << '\n';
    
    // 修改模板内联变量
    default_value<int> = 200;
    std::cout << "  更新后 default_value<int> = " << default_value<int> << '\n';
} 